home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / SML⁄NJ 93+ / Documentation / examples / textbooks / four_lectures / interp2.sml < prev    next >
Encoding:
Text File  |  1995-12-30  |  13.4 KB  |  475 lines  |  [TEXT/R*ch]

  1. (* interp2.sml : adding lists *)
  2.  
  3. signature INTERPRETER=
  4.    sig
  5.       val interpret: string -> string
  6.       val eval: bool ref
  7.       and tc  : bool ref
  8.    end;
  9.  
  10.                   (* syntax *)
  11.  
  12. signature EXPRESSION =
  13.    sig
  14.       datatype Expression =
  15.          SUMexpr of Expression * Expression   |
  16.          DIFFexpr of Expression * Expression   |
  17.          PRODexpr of Expression * Expression   |
  18.          BOOLexpr of bool   |
  19.          EQexpr of Expression * Expression   |
  20.          CONDexpr of Expression * Expression * Expression   |
  21.          CONSexpr of Expression * Expression   |
  22.          LISTexpr of Expression list   |
  23.          DECLexpr of string * Expression * Expression   |
  24.          RECDECLexpr of string * Expression * Expression   |
  25.          IDENTexpr of string   |
  26.          LAMBDAexpr of string * Expression   |
  27.          APPLexpr of Expression * Expression   |
  28.          NUMBERexpr of int
  29.    end
  30.  
  31.  
  32.               (* parsing *)
  33.  
  34. signature PARSER =
  35.    sig
  36.       structure E: EXPRESSION
  37.  
  38.       exception Lexical of string
  39.       exception Syntax of string
  40.  
  41.       val parse: string -> E.Expression
  42.    end
  43.  
  44.  
  45.                         (* environments *)
  46.  
  47. signature ENVIRONMENT =
  48.    sig
  49.       type 'object Environment
  50.  
  51.       exception Retrieve of string
  52.  
  53.       val emptyEnv: 'object Environment
  54.       val declare: string * 'object * 'object Environment -> 'object Environment
  55.       val retrieve: string * 'object Environment -> 'object
  56.    end
  57.  
  58.                         (* evaluation *)
  59. signature VALUE =
  60.    sig
  61.       type Value
  62.       exception Value
  63.  
  64.       val mkValueNumber: int -> Value
  65.           and unValueNumber: Value -> int
  66.  
  67.       val mkValueBool: bool -> Value
  68.           and unValueBool: Value -> bool
  69.  
  70.       val ValueNil: Value
  71.       val mkValueCons: Value * Value -> Value
  72.           and unValueHead: Value -> Value
  73.           and unValueTail: Value -> Value
  74.  
  75.       val eqValue: Value * Value -> bool
  76.       val printValue: Value -> string
  77.    end
  78.  
  79.  
  80. signature EVALUATOR =
  81.    sig
  82.       structure Exp: EXPRESSION
  83.       structure Val: VALUE
  84.       exception Unimplemented
  85.       val evaluate: Exp.Expression -> Val.Value
  86.    end
  87.  
  88.                   (* type checking *)
  89. signature TYPE =
  90.    sig
  91.       eqtype tyvar
  92.       val freshTyvar: unit -> tyvar
  93.       type Type 
  94.   
  95.     (*constructors and decstructors*)
  96.       exception Type
  97.       val mkTypeInt: unit -> Type
  98.           and unTypeInt: Type -> unit
  99.  
  100.       val mkTypeBool: unit -> Type
  101.           and unTypeBool: Type -> unit
  102.  
  103.       val mkTypeList: Type -> Type
  104.           and unTypeList: Type -> Type
  105.  
  106.       val mkTypeTyvar: tyvar -> Type
  107.           and unTypeTyvar: Type -> tyvar
  108.  
  109.       type subst
  110.       val Id: subst                     (* the identify substitution;   *)
  111.       val mkSubst: tyvar*Type -> subst     (* make singleton substitution; *)
  112.       val on : subst * Type -> Type     (* application;                 *)
  113.  
  114.     
  115.       val prType: Type->string          (* printing *)
  116.    end
  117.  
  118.  
  119.  
  120. signature TYPECHECKER =
  121.    sig
  122.       structure Exp: EXPRESSION
  123.       structure Type: TYPE
  124.       exception NotImplemented of string
  125.       exception TypeError of Exp.Expression * string
  126.       val typecheck: Exp.Expression -> Type.Type
  127.    end;
  128.  
  129.                   (* the interpreter*)
  130.  
  131. functor Interpreter
  132.    (structure Ty: TYPE
  133.     structure Value : VALUE
  134.     structure Parser: PARSER
  135.     structure TyCh: TYPECHECKER
  136.     structure Evaluator:EVALUATOR
  137.       sharing Parser.E = TyCh.Exp = Evaluator.Exp
  138.           and TyCh.Type = Ty
  139.           and Evaluator.Val = Value
  140.    ): INTERPRETER=
  141.  
  142. struct
  143.   val eval= ref true    (* toggle for evaluation *)
  144.   and tc  = ref true    (* toggle for type checking *)
  145.   fun interpret(str)=
  146.     let val abstsyn= Parser.parse str
  147.         val typestr= if !tc then Ty.prType(TyCh.typecheck abstsyn)
  148.                      else "(disabled)"
  149.         val valuestr= if !eval then 
  150.                          Value.printValue(Evaluator.evaluate abstsyn)
  151.                       else "(disabled)"
  152.              
  153.     in  valuestr ^ " : " ^ typestr 
  154.     end
  155.     handle Evaluator.Unimplemented => "Evaluator not fully implemented"
  156.          | TyCh.NotImplemented msg => "Type Checker not fully implemented " ^ msg
  157.          | Value.Value   => "Run-time error"
  158.          | Parser.Syntax msg => "Syntax Error: " ^ msg
  159.          | Parser.Lexical msg=> "Lexical Error: " ^ msg
  160.          | TyCh.TypeError(_,msg)=> "Type Error: " ^ msg
  161. end;
  162.                
  163.                     (* the evaluator *)
  164.  
  165. functor Evaluator
  166.   (structure Expression: EXPRESSION
  167.    structure Value: VALUE):EVALUATOR=
  168.  
  169.    struct
  170.       structure Exp= Expression
  171.       structure Val= Value
  172.       exception Unimplemented
  173.  
  174.       local
  175.          open Expression Value
  176.          fun evaluate exp =
  177.             case exp
  178.               of BOOLexpr b => mkValueBool b
  179.                | NUMBERexpr i => mkValueNumber i
  180.                | SUMexpr(e1, e2) =>
  181.                     let val e1' = evaluate e1
  182.                         val e2' = evaluate e2
  183.                     in
  184.                        mkValueNumber(unValueNumber e1' + unValueNumber e2')
  185.                     end
  186.  
  187.                | DIFFexpr(e1, e2) =>
  188.                     let val e1' = evaluate e1
  189.                         val e2' = evaluate e2
  190.                     in
  191.                        mkValueNumber(unValueNumber e1' - unValueNumber e2')
  192.                     end
  193.  
  194.                | PRODexpr(e1, e2) =>
  195.                     let val e1' = evaluate e1
  196.                         val e2' = evaluate e2
  197.                     in
  198.                        mkValueNumber(unValueNumber e1' * unValueNumber e2')
  199.                     end
  200.  
  201.                | EQexpr _ => raise Unimplemented
  202.                | CONDexpr _ => raise Unimplemented
  203.                | CONSexpr _ => raise Unimplemented
  204.                | LISTexpr _ => raise Unimplemented
  205.                | DECLexpr _ => raise Unimplemented
  206.                | RECDECLexpr _ => raise Unimplemented
  207.                | IDENTexpr _ => raise Unimplemented
  208.                | LAMBDAexpr _ => raise Unimplemented
  209.                | APPLexpr _ => raise Unimplemented
  210.  
  211.       in
  212.          val evaluate = evaluate
  213.       end
  214.    end;
  215.  
  216.                         (* the type checker *)   
  217. signature UNIFY=
  218.    sig
  219.       structure Type: TYPE
  220.       exception NotImplemented of string
  221.       exception Unify
  222.       val unify: Type.Type * Type.Type -> Type.subst
  223.    end;
  224.  
  225. functor TypeChecker
  226.   (structure Ex: EXPRESSION
  227.    structure Ty: TYPE
  228.    structure Unify: UNIFY 
  229.     sharing Unify.Type = Ty
  230.   )=
  231. struct
  232.   infix on 
  233.   val (op on) = Ty.on
  234.   structure Exp = Ex
  235.   structure Type = Ty
  236.   exception NotImplemented of string
  237.   exception TypeError of Ex.Expression * string
  238.  
  239.   fun tc (exp: Ex.Expression): Ty.Type =
  240.    (case exp of
  241.       Ex.BOOLexpr b => Ty.mkTypeBool()
  242.     | Ex.NUMBERexpr _ => Ty.mkTypeInt()
  243.     | Ex.SUMexpr(e1,e2)  => checkIntBin(e1,e2)
  244.     | Ex.DIFFexpr(e1,e2) => checkIntBin(e1,e2)
  245.     | Ex.PRODexpr(e1,e2) => checkIntBin(e1,e2)
  246.     | Ex.LISTexpr [] =>
  247.          let val new = Ty.freshTyvar ()
  248.           in Ty.mkTypeList(Ty.mkTypeTyvar  new)
  249.          end
  250.     | Ex.LISTexpr(e::es) => tc (Ex.CONSexpr(e,Ex.LISTexpr es))
  251.     | Ex.CONSexpr(e1,e2) =>
  252.         let val t1 = tc e1
  253.             val t2 = tc e2
  254.             val new = Ty.freshTyvar ()
  255.             val newt= Ty.mkTypeTyvar new
  256.             val t2' = Ty.mkTypeList newt
  257.             val S1 = Unify.unify(t2, t2')
  258.                      handle Unify.Unify=> 
  259.                      raise TypeError(e2,"expected list type")
  260.  
  261.             val S2 = Unify.unify(S1 on newt,S1 on t1)
  262.                      handle Unify.Unify=>
  263.                      raise TypeError(exp,"element and list have different types")
  264.          in S2 on (S1 on t2)
  265.         end
  266.     | Ex.EQexpr _ => raise NotImplemented "(equality)"
  267.     | Ex.CONDexpr _ => raise NotImplemented "(conditional)"
  268.     | Ex.DECLexpr _ => raise NotImplemented "(declaration)"
  269.     | Ex.RECDECLexpr _ => raise NotImplemented "(rec decl)"
  270.     | Ex.IDENTexpr _   => raise NotImplemented "(identifier)"
  271.     | Ex.LAMBDAexpr _  => raise NotImplemented "(function)"
  272.     | Ex.APPLexpr _ => raise NotImplemented    "(application)"
  273.  
  274.    )handle Unify.NotImplemented msg => raise NotImplemented msg
  275.        
  276.   and checkIntBin(e1,e2) =
  277.     let val t1 = tc e1
  278.         val _  = Ty.unTypeInt t1
  279.                  handle Ty.Type=> raise TypeError(e1,"expected int")
  280.         val t2 = tc e2
  281.         val _  = Ty.unTypeInt t2
  282.                  handle Ty.Type=> raise TypeError(e2,"expected int")
  283.      in Ty.mkTypeInt()
  284.     end;
  285.  
  286.   val typecheck = tc
  287.  
  288. end; (*TypeChecker*)
  289.  
  290.  
  291. functor Unify(Ty:TYPE):UNIFY=
  292. struct
  293.    structure Type = Ty
  294.    exception NotImplemented of string
  295.    exception Unify
  296.  
  297.    fun occurs(tv:Ty.tyvar,t:Ty.Type):bool=
  298.      (Ty.unTypeInt t; false)              handle Ty.Type=>
  299.      (Ty.unTypeBool t; false)             handle Ty.Type=>
  300.      let val tv' = Ty.unTypeTyvar t
  301.      in  tv=tv'
  302.      end                                  handle Ty.Type=>
  303.      let val t'  = Ty.unTypeList t
  304.      in  occurs(tv,t')
  305.      end                                  handle Ty.Type=>
  306.      raise NotImplemented "(the occur check)"
  307.  
  308.  
  309.    fun unify(t,t')=
  310.    let val tv = Ty.unTypeTyvar t
  311.     in let val tv' = Ty.unTypeTyvar t'
  312.         in Ty.mkSubst(tv,t')
  313.        end                                handle Ty.Type=>
  314.        if occurs(tv,t') then raise Unify
  315.        else Ty.mkSubst(tv,t')
  316.    end                                  handle Ty.Type=>
  317.    let val tv' = Ty.unTypeTyvar t'
  318.     in if occurs(tv',t) then raise Unify
  319.        else Ty.mkSubst(tv',t)
  320.    end                           handle Ty.Type=>
  321.    let val _ = Ty.unTypeInt t
  322.     in let val _ = Ty.unTypeInt t'
  323.         in Ty.Id
  324.        end handle Ty.Type=> raise Unify
  325.    end                    handle Ty.Type =>
  326.    let val _ = Ty.unTypeBool t
  327.     in let val _ = Ty.unTypeBool t'
  328.         in Ty.Id
  329.        end handle Ty.Type=> raise Unify
  330.    end                    handle Ty.Type=>
  331.    let val t = Ty.unTypeList t
  332.     in let val t' = Ty.unTypeList t'
  333.         in unify(t,t')
  334.        end handle Ty.Type => raise Unify
  335.    end                     handle Ty.Type=>
  336.    raise NotImplemented "(unify)"     
  337.  
  338. end; (*Unify*)
  339.   
  340.                      (* the basics -- nullary functors *)
  341.  
  342. functor Type():TYPE =
  343. struct
  344.   type tyvar = int
  345.   val freshTyvar =
  346.       let val r= ref 0 in fn()=>(r:= !r +1; !r) end
  347.   datatype Type = INT
  348.                 | BOOL
  349.                 | LIST of Type
  350.                 | TYVAR of tyvar  
  351.  
  352.   exception Type
  353.  
  354.   fun mkTypeInt() = INT
  355.   and unTypeInt(INT)=()
  356.     | unTypeInt(_)= raise Type
  357.  
  358.   fun mkTypeBool() = BOOL
  359.   and unTypeBool(BOOL)=()
  360.     | unTypeBool(_)= raise Type
  361.  
  362.   fun mkTypeList(t)=LIST t
  363.   and unTypeList(LIST t)= t
  364.     | unTypeList(_)= raise Type
  365.  
  366.   fun mkTypeTyvar tv = TYVAR tv
  367.   and unTypeTyvar(TYVAR tv) = tv
  368.     | unTypeTyvar _ = raise Type
  369.   
  370.   type subst = Type -> Type
  371.  
  372.   fun Id x = x
  373.   fun mkSubst(tv,ty)=
  374.      let fun su(TYVAR tv')= if tv=tv' then ty else TYVAR tv'
  375.          |   su(INT) = INT
  376.          |   su(BOOL)= BOOL
  377.          |   su(LIST ty') = LIST (su ty')
  378.       in su
  379.      end
  380.  
  381.  
  382.   val O = (op o)
  383.  
  384.   fun on(S,t)= S(t)
  385.  
  386.   fun intToString(i:int)=  (if i<0 then " -" else "")^ natToString (abs i)
  387.   and natToString(n:int)=
  388.       let val d = n div 10 in
  389.         if d = 0 then chr(ord"0" + n)
  390.         else natToString(d)^ chr(ord"0" + (n mod 10))
  391.       end
  392.  
  393.   fun prType INT = "int"
  394.   |   prType BOOL= "bool"
  395.   |   prType (LIST ty) = "(" ^ prType ty ^ ")list"
  396.   |   prType (TYVAR tv) = "a" ^ intToString tv
  397. end;
  398.  
  399.  
  400.  
  401. functor Expression(): EXPRESSION =
  402.    struct
  403.       type 'a pair = 'a * 'a
  404.  
  405.       datatype Expression =
  406.          SUMexpr of Expression pair   |
  407.          DIFFexpr of Expression pair   |
  408.          PRODexpr of Expression pair   |
  409.          BOOLexpr of bool   |
  410.          EQexpr of Expression pair   |
  411.          CONDexpr of Expression * Expression * Expression   |
  412.          CONSexpr of Expression pair   |
  413.          LISTexpr of Expression list   |
  414.          DECLexpr of string * Expression * Expression   |
  415.          RECDECLexpr of string * Expression * Expression   |
  416.          IDENTexpr of string   |
  417.          LAMBDAexpr of string * Expression   |
  418.          APPLexpr of Expression * Expression   |
  419.          NUMBERexpr of int
  420.    end;
  421.  
  422. functor Value(): VALUE =
  423.    struct
  424.       type 'a pair = 'a * 'a
  425.  
  426.       datatype Value = NUMBERvalue of int   |
  427.                       BOOLvalue of bool   |
  428.                       NILvalue   |
  429.                       CONSvalue of Value pair
  430.  
  431.       exception Value
  432.  
  433.       val mkValueNumber = NUMBERvalue
  434.       val mkValueBool = BOOLvalue
  435.  
  436.       val ValueNil = NILvalue
  437.       val mkValueCons = CONSvalue
  438.  
  439.       fun unValueNumber(NUMBERvalue(i)) = i   |
  440.           unValueNumber(_) = raise Value
  441.  
  442.       fun unValueBool(BOOLvalue(b)) = b   |
  443.           unValueBool(_) = raise Value
  444.  
  445.       fun unValueHead(CONSvalue(c, _)) = c   |
  446.           unValueHead(_) = raise Value
  447.  
  448.       fun unValueTail(CONSvalue(_, c)) = c   |
  449.           unValueTail(_) = raise Value
  450.  
  451.       fun eqValue(c1, c2) = (c1 = c2)
  452.  
  453.                 (* Pretty-printing *)
  454.       fun intToString(i:int)=  (if i<0 then " -" else "")^ natToString (abs i)
  455.       and natToString(n:int)=
  456.           let val d = n div 10 in
  457.             if d = 0 then chr(ord"0" + n)
  458.             else natToString(d)^ chr(ord"0" + (n mod 10))
  459.           end
  460.       fun printValue(NUMBERvalue(i)) = intToString(i)   |
  461.           printValue(BOOLvalue(true)) = "true"   |
  462.           printValue(BOOLvalue(false)) = "false"   |
  463.           printValue(NILvalue) = "[]"   |
  464.           printValue(CONSvalue(cons)) = "[" ^ printValueList(cons) ^ "]"
  465.           and printValueList(hd, NILvalue) = printValue(hd)   |
  466.               printValueList(hd, CONSvalue(tl)) =
  467.                  printValue(hd) ^ ", " ^ printValueList(tl)   |
  468.               printValueList(_) = raise Value
  469.    end;
  470.  
  471.  
  472.  
  473.  
  474.  
  475.